/*  dgsh.c - dgsh - shell like bash
 * Autor        Diego Gomes da Silva    nUSP 7656467
 *              Alfredo Lima Porfirio   nUSP 7236614
 * Sistemas Operacionais 2
 * Professor Monaco
 * ICMC/USP
 */


#include <dgsh.h>
#include <io-redirect.h>
#include <build-in.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>





void tokens ( ControlDgsh *controlDgsh )
{

        char  *aux, *save1, *save2;
        
        printf ( "[DGSH-Debug] %s\n", controlDgsh->userLine );
        aux = strtok_r ( controlDgsh->userLine, "|", &save1 );
        controlDgsh->num_pipes = 0;
        controlDgsh->command = ( Command * ) malloc ( sizeof ( Command ) );
        while (  aux != NULL  ) {

                char *pch;
                
                pch = strtok_r ( aux, " ", &save2 );
                printf ( "[DGSH-Debug] %s\n", aux );
                controlDgsh->size_args = 0;

                controlDgsh->command[ controlDgsh->num_pipes++][controlDgsh->size_args++] = aux;

                while ( pch != NULL ) {
                        pch = strtok_r ( NULL, " ", &save2 );
                        controlDgsh->command[ controlDgsh->num_pipes][controlDgsh->size_args++] = pch;
                }
                aux = strtok_r ( NULL, "|", &save1 );
                if ( aux == NULL ) break;



                controlDgsh->command = ( Command * ) realloc ( controlDgsh->command , sizeof ( Command ) * ( controlDgsh->num_pipes ) );
        }
}




void initControlDgsh ( ControlDgsh *controlDgsh )
{
        controlDgsh->fd_in = controlDgsh->fd_in2 = controlDgsh->fd_out = controlDgsh->fd_out2  = controlDgsh->pid = controlDgsh->status = 0 ;
        controlDgsh->continuous = 1;
}

int main ( int argc, char *argv[] )
{
        int iteradorPipe = 0 ;
        ControlDgsh controlDgsh;
        if ( chdir ( "." ) == -1 ) {
                perror ( "chDir error" );
        }
        initControlDgsh ( &controlDgsh );
       
        /* Main loop */
        while ( controlDgsh.continuous ) {
                close_io_redirect ( &controlDgsh );
                printf ( PROMPT_STRING );
                if ( getcwd ( controlDgsh.cwd, sizeof ( controlDgsh.cwd ) ) != NULL )
                        fprintf ( stdout, "@:%s$ ", controlDgsh.cwd );
                else
                        perror ( "getcwd() error" );
                fgets ( controlDgsh.userLine, MAX_COMMAND_SIZE, stdin );
                if ( ( strlen ( controlDgsh.userLine ) > 0 ) && ( controlDgsh.userLine[strlen ( controlDgsh.userLine ) - 1] == '\n' ) ) controlDgsh.userLine[strlen ( controlDgsh.userLine ) - 1] = '\0';

                tokens ( &controlDgsh );


                iteradorPipe = controlDgsh.num_pipes ;
                while ( --iteradorPipe > -1 ) {

                        open_io_redirect ( &controlDgsh );

                        // Execução em loop aqui
                        // todo programa tem que fazer o redirect io!!

                        if ( !exec_built_in ( &controlDgsh,  iteradorPipe) ) {
                                if ( ( controlDgsh.pid = fork() ) < 0 ) fatal ( controlDgsh.command[iteradorPipe][0] );
                                if ( controlDgsh.pid > 0 ) { /* Parent */
                                        wait ( &controlDgsh.status );
                                } else {   /* Child */
                                        execvp ( controlDgsh.command[iteradorPipe][0], controlDgsh.command[iteradorPipe] );
                                        /* Only if exec has failed */
                                        fprintf ( stderr, "%s: Command not found\n", controlDgsh.command[iteradorPipe][0] );
                                        return EXIT_FAILURE;
                                }
                        }

                }
                //free ( controlDgsh.command );
        }

        printf ( "Bye\n" );
        return EXIT_SUCCESS;
}

